package com.joysuch.wwyt.api.mh.service.impl;

import com.joysuch.wwyt.api.mh.bean.MhPlatformBean;
import com.joysuch.wwyt.api.mh.bean.MhPlatformFieldBean;
import com.joysuch.wwyt.api.mh.bean.MhPlatformPointBean;
import com.joysuch.wwyt.api.mh.entity.MhPlatform;
import com.joysuch.wwyt.api.mh.entity.MhPlatformField;
import com.joysuch.wwyt.api.mh.entity.MhPlatformPoint;
import com.joysuch.wwyt.api.mh.entity.MonitorPointAPIData;
import com.joysuch.wwyt.api.mh.repository.MhPlatformDao;
import com.joysuch.wwyt.api.mh.repository.MhPlatformFieldDao;
import com.joysuch.wwyt.api.mh.repository.MhPlatformPointDao;
import com.joysuch.wwyt.api.mh.repository.MonitorPointDataAPIRepository;
import com.joysuch.wwyt.api.mh.service.MhPlatformDataDockingService;
import com.joysuch.wwyt.api.mh.service.MhPlatformSocketService;
import com.joysuch.wwyt.core.bean.SimpleSelectListBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.entity.BaseTypeGroupItem;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.security.ShiroUser;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.mh.entity.MhMonitoringType;
import com.joysuch.wwyt.mh.repository.MhMonitoringTypeDao;
import com.joysuch.wwyt.util.JdbcTemplateFactory;
import com.joysuch.wwyt.util.PageableUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PreDestroy;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
@Transactional
@Slf4j
public class MhPlatformDataDockingServiceImpl implements MhPlatformDataDockingService, ApplicationRunner {

    @Autowired
    private MhPlatformDao mhPlatformDao;
    @Autowired
    private MhPlatformPointDao mhPlatformPointDao;
    @Autowired
    private MhPlatformFieldDao mhPlatformFieldDao;
    @Autowired
    private MonitorPointDataAPIRepository monitorPointDataAPIRepository;
    @Autowired
    private MhMonitoringTypeDao mhMonitoringTypeDao;
    @Autowired
    private MhPlatformSocketService socketService;
    @Autowired
    private BaseTypeGroupItemDao baseTypeGroupItemDao;

    /**
     * 增加平台
     *
     * @param bean
     * @return
     */
    @Override
    public MhPlatform addPlatform(MhPlatformBean bean) {
        MhPlatform mhPlatform = new MhPlatform();
        BeanUtils.copyProperties(bean, mhPlatform);
        int count = mhPlatformDao.countByName(bean.getName());
        if (count > 0) {
            throw new IllegalArgumentException("平台名称已存在");
        }
        MhPlatform save = mhPlatformDao.save(mhPlatform);
        //平台数据对接
        mhPointDataTransfer(save);
        return save;
    }

    /**
     * 修改平台
     *
     * @param bean
     * @return
     */
    @Override
    public MhPlatform updatePlatform(MhPlatformBean bean) {
        MhPlatform mhPlatform = mhPlatformDao.findById(bean.getId()).orElseThrow(() -> new IllegalArgumentException("平台不存在"));
        //判断非必要更新
        boolean jdbcUpdate = judgeJdbcUpdate(bean, mhPlatform);
        boolean frequencyUpdate = judgeFrequencyUpdate(bean, mhPlatform);
        BeanUtils.copyProperties(bean, mhPlatform);
        int count = mhPlatformDao.countByName(bean.getName());
        if (count > 1) {
            throw new IllegalArgumentException("平台名称已存在");
        }
        MhPlatform save = mhPlatformDao.save(mhPlatform);
        if (jdbcUpdate) {
            removeJdbcCache(save);
        }
        if (frequencyUpdate) {
            removeFutureCache(getJdbcKey(save));
            mhPointDataTransfer(save);
        }
        return save;
    }

    private boolean judgeJdbcUpdate(MhPlatformBean bean, MhPlatform platform) {
        return !Objects.equals(bean.getAccount(), platform.getAccount())
                || !Objects.equals(bean.getPassword(), platform.getPassword())
                || !Objects.equals(bean.getIpLibraryName(), platform.getIpLibraryName());
    }

    private boolean judgeFrequencyUpdate(MhPlatformBean bean, MhPlatform platform) {
        return !Objects.equals(bean.getFrequency(), platform.getFrequency());
    }

    /**
     * 查看平台
     *
     * @param id
     * @return
     */
    @Override
    public MhPlatformBean getPlatformById(Long id) {
        MhPlatform mhPlatform = mhPlatformDao.findById(id).orElseThrow(() -> new IllegalArgumentException("平台不存在"));
        MhPlatformBean bean = new MhPlatformBean();
        // BeanUtils.copyProperties(mhPlatform, bean);
        // BeanUtils.copyProperties(mhPlatform, bean);
        bean.setId(mhPlatform.getId());
        //平台名称
        bean.setName(mhPlatform.getName());
        //更新频率
        bean.setFrequency(mhPlatform.getFrequency());
        //传输方式id:1DB,2Rest,3Socket
        bean.setTransmissionModeId(mhPlatform.getTransmissionModeId());
        //账号
        bean.setAccount(mhPlatform.getAccount());
        //密码
        bean.setPassword(mhPlatform.getPassword());
        //IP库名
        bean.setIpLibraryName(mhPlatform.getIpLibraryName());
        //表名称
        bean.setTableName(mhPlatform.getTableName());
        //URL地址
        bean.setUrl(mhPlatform.getUrl());
        if (mhPlatform.getTransmissionModeId() != null && mhPlatform.getTransmissionModeId() == 1) {
            bean.setTransmissionModeName("DB");
        } else if (mhPlatform.getTransmissionModeId() != null && mhPlatform.getTransmissionModeId() == 2) {
            bean.setTransmissionModeName("Rest");
        } else if (mhPlatform.getTransmissionModeId() != null && mhPlatform.getTransmissionModeId() == 3) {
            bean.setTransmissionModeName("Socket");
        }
        //加密方式
        bean.setEncryptionType(mhPlatform.getEncryptionType());
        if (mhPlatform.getEncryptionType() != null) {
            Optional<BaseTypeGroupItem> ect = baseTypeGroupItemDao.findById(mhPlatform.getEncryptionType());
            if (ect.isPresent()) {
                bean.setEncryptionTypeName(ect.get().getName());
            }
        }
        //平台自定义字段
        List<MhPlatformField> fields = mhPlatformFieldDao.findByPlatformId(id);
        List<MhPlatformFieldBean> fieldBeanList = new ArrayList<>();
        for (MhPlatformField field : fields) {
            MhPlatformFieldBean fieldBean = new MhPlatformFieldBean();
            BeanUtils.copyProperties(field, fieldBean);
            if (field.getParentId() != null) {
                MhPlatformField pField = mhPlatformFieldDao.findById(field.getParentId()).orElseThrow(() -> new IllegalArgumentException("字段不存在"));
                fieldBean.setParentName(pField.getFieldName());
            }
            fieldBeanList.add(fieldBean);
        }
        bean.setFieldBeanList(fieldBeanList);
        return bean;
    }

    /**
     * 获取平台列表
     *
     * @return
     */
    @Override
    public List<MhPlatformBean> getPlatformList() {
        List<MhPlatform> all = mhPlatformDao.findAll();
        List<MhPlatformBean> list = new ArrayList<>();
        for (MhPlatform platform : all) {
            MhPlatformBean bean = new MhPlatformBean();
            BeanUtils.copyProperties(platform, bean);
            list.add(bean);
        }
        return list;
    }

    /**
     * 删除平台
     *
     * @param id
     */
    @Override
    public void deletePlatformById(Long id) {
        List<MhPlatformPoint> list = mhPlatformPointDao.findByPlatformId(id);
        if (!CollectionUtils.isEmpty(list)) {
            throw new IllegalArgumentException("请先删除该平台下的监测点");
        }
        MhPlatform one = mhPlatformDao.getOne(id);
        removeCache(one);
        mhPlatformDao.deleteById(id);

    }

    private void removeCache(MhPlatform one) {
        String jdbcKey = removeJdbcCache(one);
        removeFutureCache(jdbcKey);
        log.info("remove jdbc&future cache，MhPlatform id:{}", one.getId());
    }

    private void removeFutureCache(String jdbcKey) {
        Future future = FUTURE_MAP.get(jdbcKey);
        if (future != null) {
            future.cancel(true);
        }
        FUTURE_MAP.remove(jdbcKey);
    }

    private String removeJdbcCache(MhPlatform one) {
        String jdbcKey = getJdbcKey(one);
        NamedParameterJdbcTemplate template = JDBC_MAP.get(jdbcKey);
        if (template != null) {
            closeDataSource(template);
        }
        JDBC_MAP.remove(jdbcKey);
        return jdbcKey;
    }

    /**
     * 增加监测点
     *
     * @param list
     * @return
     */
    @Override
    public void addPoint(List<MhPlatformPointBean> list) {
        if (!CollectionUtils.isEmpty(list)) {
            MhPlatformPointBean mhPlatformPointBean = list.get(0);
            List<String> codeList = mhPlatformPointDao.getPointCodeByPlatformId(mhPlatformPointBean.getPlatformId());
            List<MhPlatformPoint> mList = new ArrayList<>();
            for (MhPlatformPointBean bean : list) {
                if (!codeList.contains(bean.getPointCode())) {
                    MhPlatformPoint point = new MhPlatformPoint();
                    BeanUtils.copyProperties(bean, point);
                    point.setCorrectionFactor(Double.valueOf(1));
                    point.setSwitchState(1);
                    mList.add(point);
                }
            }
            if (!CollectionUtils.isEmpty(mList)) {
                mhPlatformPointDao.saveAll(mList);
            }
        }

    }

    /**
     * 修改监测点
     *
     * @param bean
     * @return
     */
    @Override
    public MhPlatformPoint editPoint(MhPlatformPointBean bean) {
        MhPlatformPoint point = mhPlatformPointDao.findById(bean.getId()).orElseThrow(() -> new IllegalArgumentException("监测点不存在"));
        //对接平台编号/名称
        point.setCodeOrName(bean.getCodeOrName());
        //校正系数
        point.setCorrectionFactor(bean.getCorrectionFactor());
        //接入开关:0关,1开
        point.setSwitchState(bean.getSwitchState());
        MhPlatformPoint save = mhPlatformPointDao.save(point);
        return save;
    }

    /**
     * 查看监测点
     *
     * @param id
     * @return
     */
    @Override
    public MhPlatformPointBean getPointById(Long id) {
        MhPlatformPoint point = mhPlatformPointDao.findById(id).orElseThrow(() -> new IllegalArgumentException("监测点不存在"));
        MhPlatformPointBean bean = new MhPlatformPointBean();
        BeanUtils.copyProperties(point, bean);
        if (point.getSwitchState() == 1) {
            bean.setSwitchName("开");
        } else if (point.getSwitchState() == 0) {
            bean.setSwitchName("关");
        }
        if (point.getPointTypeId() != null) {
            Optional<MhMonitoringType> byId = mhMonitoringTypeDao.findById(point.getPointTypeId());
            if (byId.isPresent()) {
                bean.setPointTypeName(byId.get().getName());
            }
        }
        return bean;
    }

    /**
     * 删除监测点
     *
     * @param id
     */
    @Override
    public void deletePointById(Long id) {
        mhPlatformPointDao.deleteById(id);
    }

    /**
     * 分页查询监测点
     *
     * @param page
     * @return
     */
    @Override
    public ResultBean pagePoint(Pageable page, Long platformId, String codeOrName) {
        List<MhPlatformPoint> all = new ArrayList<>();
        if (platformId == null) {
            all = mhPlatformPointDao.findAll();
        } else {
            all = mhPlatformPointDao.findByPlatformId(platformId);
        }
        List<MhPlatformPointBean> list = new ArrayList<>();
        for (MhPlatformPoint point : all) {
            MhPlatformPointBean bean = new MhPlatformPointBean();
            BeanUtils.copyProperties(point, bean);
            if (point.getSwitchState() == 1) {
                bean.setSwitchName("开");
            } else if (point.getSwitchState() == 0) {
                bean.setSwitchName("关");
            }
            if (point.getPointTypeId() != null) {
                Optional<MhMonitoringType> byId = mhMonitoringTypeDao.findById(point.getPointTypeId());
                if (byId.isPresent()) {
                    bean.setPointTypeName(byId.get().getName());
                }

            }
            if (StringUtils.isNotBlank(codeOrName)) {
                if (point.getPointCode().contains(codeOrName) || point.getPointName().contains(codeOrName)) {
                    list.add(bean);
                }
            } else {
                list.add(bean);
            }
        }

        if (CollectionUtils.isEmpty(list)) {
            return ResultBean.success(list);
        }
        List<MhPlatformPointBean> resultList = list.stream().sorted((a, b) -> b.getId().intValue() - a.getId().intValue()).collect(Collectors.toList());
        List<MhPlatformPointBean> reList = PageableUtil
                .getList(page.getPageNumber(), page.getPageSize(), resultList);
        if (CollectionUtils.isEmpty(reList)) {
            return ResultBean.success(reList);
        } else {
            return ResultBean.pageData(reList, list.size());
        }
    }

    /**
     * 保存平台字段
     *
     * @param bean
     * @return
     */
    @Override
    public MhPlatformField saveField(MhPlatformFieldBean bean) {
        MhPlatformField field = new MhPlatformField();
        if (bean.getId() != null) {
            field = mhPlatformFieldDao.findById(bean.getId()).orElseThrow(() -> new IllegalArgumentException("字段不存在"));
        }
        BeanUtils.copyProperties(bean, field);
        MhPlatformField save = mhPlatformFieldDao.save(field);
        int count = 0;
        if (save.getParentId() != null) {
            count = mhPlatformFieldDao.countByFieldNameAndPlatformIdAndParentId(save.getFieldName(), save.getPlatformId(), save.getParentId());
        } else {
            count = mhPlatformFieldDao.countByFieldNameAndPlatformId(save.getFieldName(), save.getPlatformId());
        }
        if (count > 1) {
            throw new IllegalArgumentException("该字段已存在");
        }

        return save;
    }

    /**
     * 删除平台字段
     *
     * @param id
     * @return
     */
    @Override
    public void deleteFieldById(Long id) {
        mhPlatformFieldDao.deleteById(id);
    }

    /**
     * 获取平台字段
     *
     * @param id
     * @return
     */
    @Override
    public List<SimpleSelectListBean> getFieldLIstById(Long id) {
        List<MhPlatformField> fList = mhPlatformFieldDao.findByPlatformId(id);
        List<SimpleSelectListBean> list = new ArrayList<>();
        for (MhPlatformField f : fList) {
            SimpleSelectListBean bean = new SimpleSelectListBean();
            bean.setValue(f.getId());
            bean.setLabel(f.getFieldName());
            list.add(bean);
        }
        return list;
    }

    /**
     * 获取台数据
     *
     * @return
     */
    @Override
    public ResultBean getData(Long id) {
        Date now = new Date();
        long time = 10 * 60 * 1000;//10分钟
        Date date = new Date(now.getTime() - time);
        //获取最近10分钟数据
        List<MonitorPointAPIData> list = monitorPointDataAPIRepository.getRealTimeData(id, date, now);
        return ResultBean.success(list);
    }

    /**
     * two Map -- key:  tenentId:orgCode:id(plateFormId)
     */
    private static final Map<String, NamedParameterJdbcTemplate> JDBC_MAP = new ConcurrentHashMap();
    private static final Map<String, Future> FUTURE_MAP = new ConcurrentHashMap<>();

    private static final ScheduledThreadPoolExecutor taskScheduler = new ScheduledThreadPoolExecutor(5, r -> {
        Thread thread = new Thread(r, "data transfer worker");
        thread.setDaemon(true);
        return thread;
    });

    private String getJdbcKey(MhPlatform mhPlatform) {
        StringBuilder builder = new StringBuilder();
        String orgCode = mhPlatform.getOrgCode().substring(0, 7);
        builder.append(mhPlatform.getTenentId())
                .append(":")
                .append(orgCode)
                .append(":")
                .append(mhPlatform.getId());
        return builder.toString();
    }

    @Override
    public void run(ApplicationArguments args) {
        List<MhPlatform> list = mhPlatformDao.findAll();
        //目前只支持DB,Socket
        list = list.stream().filter(r -> r.getTransmissionModeId() != null &&
                (r.getTransmissionModeId() == 3 || r.getTransmissionModeId() == 1)).collect(Collectors.toList());
        for (MhPlatform platform : list) {
            if (platform.getTransmissionModeId() == 1) {
                //DB
                mhPointDataTransfer(platform);
            } else if (platform.getTransmissionModeId() == 3) {
                //Socket
                socketService.transferMhPointBySocket(platform.getId());
            }
        }
    }

    private void mhPointDataTransfer(MhPlatform platform) {
        log.info("platform transfer begin");
        if (platform.getFrequency() == null || platform.getFrequency() <= 0) {
            return;
        }
        //准备连接池
        String jdbcKey = getJdbcKey(platform);
        NamedParameterJdbcTemplate jdbcTemplate = JDBC_MAP.get(jdbcKey);
        if (jdbcTemplate == null) {
            jdbcTemplate = JdbcTemplateFactory.getJdbcTemplate(platform.getIpLibraryName(),
                    platform.getAccount(), platform.getPassword());
            JDBC_MAP.put(jdbcKey, jdbcTemplate);
        }

        ScheduledFuture<?> scheduledFuture = taskScheduler.scheduleAtFixedRate(() -> {
            log.info("platform transfer schedule begin");
            int size = 0;
            try {
                setUser(platform);
                //平台需要传值字段
                List<MhPlatformField> fields = mhPlatformFieldDao.findByPlatformId(platform.getId());
                if (CollectionUtils.isEmpty(fields)) return;
                //判断where字段是否存在
                String fieldName = hasTagName(fields);
                if (fieldName == null) {
                    return;
                }

                //执行sql
                String insertSql = getInsertSql(platform, fields);
                //查询平台下所有开启的监测点
                List<MhPlatformPoint> pointList = mhPlatformPointDao.findByPlatformIdAndSwitchState(platform.getId(), 1);
                if (CollectionUtils.isEmpty(pointList)) return;
                //查询监测点检测数据
                List<String> collect = pointList.stream().filter(r -> r.getPointCode() != null)
                        .map(r -> r.getPointCode()).collect(Collectors.toList());
                List<MonitorPointAPIData> resultList = getMonitorPointAPIData(collect);
                if (CollectionUtils.isEmpty(resultList)) {
                    log.info("platform transfer monitor point is empty");
                    return;
                }
                size = resultList.size();
                for (MonitorPointAPIData data : resultList) {
                    //先查询数据是否已存在,再决定update还是insert
                    String selectSql = getSelectSql(platform, fieldName);
                    SqlParameterSource selectSqlParameterSource = getSelectSqlParameterSource(data, fieldName);
                    Integer id = null;
                    try {
                        id = doSelectSql(jdbcKey, selectSql, selectSqlParameterSource);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //设置具体值
                    SqlParameterSource sqlParameterSource = getInsertSqlParameterSource(fields, data);
                    if (id != null) {
                        String updateSql = getUpdateSql(platform, fields, id);
                        doInsertOrUpdateSql(jdbcKey, updateSql, sqlParameterSource);
                    } else {
                        doInsertOrUpdateSql(jdbcKey, insertSql, sqlParameterSource);
                    }
                }
            } catch (Exception e) {
                log.error("platform data transfer fail:" + e.getMessage());
            }
            log.info("platform data transfer success, dataSize:" + size);
        }, 0, platform.getFrequency(), TimeUnit.SECONDS);
        FUTURE_MAP.put(jdbcKey, scheduledFuture);
    }

    private String hasTagName(List<MhPlatformField> fields) {
        for (MhPlatformField field : fields) {
            String mapFieldName = field.getMapFieldName();
            if ("tagName".equals(mapFieldName)) {
                return field.getFieldName();
            }
        }
        return null;
    }

    private void setUser(MhPlatform platform) {
        ShiroUser user = new ShiroUser();
        user.setTenentId(platform.getTenentId());
        //取的不定，两个都塞值
        user.setDepartCode(platform.getOrgCode().substring(0, 7));
        user.setCompanyCode(platform.getOrgCode().substring(0, 7));
        Context.setCurrentUser(user);
    }

    private List<MonitorPointAPIData> getMonitorPointAPIData(List<String> collect) {
        Date now = new Date();
        long time = 10 * 60 * 1000;//10分钟
        Date from = new Date(now.getTime() - time);
        //小英: 服务器时间存在不准的情况，结束时间后延10分钟
        Date to = new Date(now.getTime() + 10 * 60 * 1000);
        return monitorPointDataAPIRepository.findByTagNameInAndTagTimeBetween(collect, from, to);
    }

    private Integer doSelectSql(String jdbcKey, String selectSql, SqlParameterSource selectSqlParameterSource) {
        NamedParameterJdbcTemplate template = JDBC_MAP.get(jdbcKey);
        return template != null ? template.queryForObject(selectSql, selectSqlParameterSource, Integer.class) : null;
    }

    private void doSql(String jdbcKey, String sql, List<SqlParameterSource> sourceList) {
        NamedParameterJdbcTemplate template = JDBC_MAP.get(jdbcKey);
        if (template != null) {
            try {
                template.batchUpdate(sql, sourceList.toArray(new SqlParameterSource[]{}));
            } catch (Exception e) {
                log.error("platform data transfer error:{}", e.getMessage());
            }
        }
    }

    private void doInsertOrUpdateSql(String jdbcKey, String sql, SqlParameterSource sqlParameterSource) {
        NamedParameterJdbcTemplate template = JDBC_MAP.get(jdbcKey);
        if (template != null) {
            try {
                template.update(sql, sqlParameterSource);
            } catch (Exception e) {
                log.error("platform data transfer error:{}", e.getMessage());
            }
        }
    }

    private String getUpdateSql(MhPlatform platform, List<MhPlatformField> fields, Integer id) {
        StringBuilder builder = new StringBuilder("update ");
        builder.append(platform.getTableName()).append(" set ");
        for (int i = 0; i < fields.size(); i++) {
            MhPlatformField field = fields.get(i);
            builder.append(field.getFieldName()).append("=:").append(field.getFieldName());
            if (i != fields.size() - 1) {
                builder.append(",");
            }
        }
        builder.append(" where DataID").append("='").append(id).append("'");
        return builder.toString();
    }

    private String getSelectSql(MhPlatform platform, String fieldName) {
        StringBuilder builder = new StringBuilder("select DataID from ");
        builder.append(platform.getTableName());
        builder.append(" where ");
        builder.append(fieldName);
        builder.append("=:");
        builder.append(fieldName);
        builder.append(" order by DataID desc limit 1");
        return builder.toString();
    }

    private String getInsertSql(MhPlatform platform, List<MhPlatformField> fields) {
        StringBuilder tableBuilder = new StringBuilder("insert into ");
        tableBuilder.append(platform.getTableName()).append("(");
        StringBuilder valueBuilder = new StringBuilder();
        valueBuilder.append(" values(");
        for (int i = 0; i < fields.size(); i++) {
            MhPlatformField field = fields.get(i);
            String fieldName = field.getFieldName();
            tableBuilder.append(fieldName);
            valueBuilder.append(":");
            valueBuilder.append(fieldName);
            if (i != fields.size() - 1) {
                tableBuilder.append(",");
                valueBuilder.append(",");
            } else {
                tableBuilder.append(")");
                valueBuilder.append(")");
            }
        }
        return tableBuilder.append(valueBuilder).toString();
    }

    private SqlParameterSource getSelectSqlParameterSource(MonitorPointAPIData data, String fieldName) {
        MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
        try {
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor("tagName", data.getClass());
            Method readMethod = propertyDescriptor.getReadMethod();
            Object invoke = readMethod.invoke(data);
            sqlParameterSource.addValue(fieldName, invoke);
            return sqlParameterSource;
        } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return sqlParameterSource;
    }

    private SqlParameterSource getInsertSqlParameterSource(List<MhPlatformField> fields, MonitorPointAPIData data) {
        MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
        for (int i = 0; i < fields.size(); i++) {
            MhPlatformField field = fields.get(i);
            String mapFieldName = field.getMapFieldName();
            String fieldName = field.getFieldName();
            Object resultData;
            try {
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(mapFieldName, data.getClass());
                Method readMethod = propertyDescriptor.getReadMethod();
                resultData = readMethod.invoke(data);
                String format = field.getFormat();
                if (!org.springframework.util.StringUtils.isEmpty(format)) {
                    try {
                        SimpleDateFormat dateFormat = SimpleDateFormatCache.getFormat(format);
                        resultData = dateFormat.format((Timestamp) resultData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                //无此字段，取固定值
                resultData = field.getFixedValue();
            }
            sqlParameterSource.addValue(fieldName, resultData);
        }
        return sqlParameterSource;
    }

    @PreDestroy
    public void closeTaskJdbc() {
        for (Future future : FUTURE_MAP.values()) {
            if (future != null) {
                future.cancel(true);
            }
        }
        for (NamedParameterJdbcTemplate template : JDBC_MAP.values()) {
            closeDataSource(template);
        }
        if (!taskScheduler.isShutdown()) {
            taskScheduler.shutdownNow();
        }
    }

    private void closeDataSource(NamedParameterJdbcTemplate template) {
        JdbcTemplate jdbcTemplate = template.getJdbcTemplate();
        DataSource dataSource = jdbcTemplate.getDataSource();
        if (dataSource != null) {
            try {
                Connection connection = dataSource.getConnection();
                if (!connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
